/**
 * 深拷贝实现
 * 支持对象、数组、Date、RegExp、Map、Set等复杂类型的深拷贝
 */

// 基础深拷贝实现
function deepClone(obj, hash = new WeakMap()) {
  // 处理基本类型和null
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  
  // 处理Date对象
  if (obj instanceof Date) {
    return new Date(obj);
  }
  
  // 处理RegExp对象
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }
  
  // 处理Map对象
  if (obj instanceof Map) {
    const result = new Map();
    obj.forEach((value, key) => {
      result.set(key, deepClone(value, hash));
    });
    return result;
  }
  
  // 处理Set对象
  if (obj instanceof Set) {
    const result = new Set();
    obj.forEach(value => {
      result.add(deepClone(value, hash));
    });
    return result;
  }
  
  // 处理数组
  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item, hash));
  }
  
  // 处理普通对象 - 使用WeakMap解决循环引用
  if (hash.has(obj)) {
    return hash.get(obj);
  }
  
  const result = Object.create(Object.getPrototypeOf(obj));
  hash.set(obj, result);
  
  // 复制所有属性（包括不可枚举属性）
  const allProperties = Object.getOwnPropertyNames(obj);
  const symbolProperties = Object.getOwnPropertySymbols(obj);
  
  [...allProperties, ...symbolProperties].forEach(key => {
    const descriptor = Object.getOwnPropertyDescriptor(obj, key);
    if (descriptor) {
      if (typeof obj[key] === 'object' && obj[key] !== null) {
        descriptor.value = deepClone(obj[key], hash);
      }
      Object.defineProperty(result, key, descriptor);
    }
  });
  
  return result;
}

// 简化版深拷贝（面试常用）
function simpleDeepClone(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);
  
  const result = Array.isArray(obj) ? [] : {};
  
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      result[key] = simpleDeepClone(obj[key]);
    }
  }
  
  return result;
}

// JSON深拷贝（有局限性）
function jsonDeepClone(obj) {
  return JSON.parse(JSON.stringify(obj));
}

// 测试用例
console.log('=== 深拷贝测试 ===');

// 测试基本类型
const num = 123;
const str = 'hello';
const bool = true;
const nul = null;
const undef = undefined;

console.log('基本类型测试:');
console.log('数字:', deepClone(num) === num); // true
console.log('字符串:', deepClone(str) === str); // true
console.log('布尔值:', deepClone(bool) === bool); // true
console.log('null:', deepClone(nul) === nul); // true
console.log('undefined:', deepClone(undef) === undef); // true

// 测试复杂对象
const obj = {
  name: '张三',
  age: 25,
  hobbies: ['篮球', '游泳', '阅读'],
  address: {
    city: '北京',
    district: '朝阳区'
  },
  birthDate: new Date('1998-05-20'),
  regex: /^test$/i,
  [Symbol('id')]: 12345
};

// 添加循环引用
obj.self = obj;

const clonedObj = deepClone(obj);
console.log('\n复杂对象测试:');
console.log('对象相等性:', clonedObj !== obj); // true
console.log('属性相等性:', clonedObj.name === obj.name); // true
console.log('数组引用不同:', clonedObj.hobbies !== obj.hobbies); // true
console.log('嵌套对象引用不同:', clonedObj.address !== obj.address); // true
console.log('循环引用处理:', clonedObj.self === clonedObj); // true

// 测试Map和Set
const map = new Map([['key1', 'value1'], ['key2', { nested: 'object' }]]);
const set = new Set([1, 2, 3, { complex: 'data' }]);

const clonedMap = deepClone(map);
const clonedSet = deepClone(set);

console.log('\nMap/Set测试:');
console.log('Map引用不同:', clonedMap !== map); // true
console.log('Set引用不同:', clonedSet !== set); // true
console.log('Map内容相等:', clonedMap.get('key1') === map.get('key1')); // true

// 性能对比测试
console.log('\n=== 性能对比 ===');
const testData = {
  users: Array.from({ length: 1000 }, (_, i) => ({
    id: i,
    name: `User${i}`,
    profile: { age: i % 100, tags: Array.from({ length: 10 }, (_, j) => `tag${j}`) }
  }))
};

console.time('递归深拷贝');
const result1 = deepClone(testData);
console.timeEnd('递归深拷贝');

console.time('简化深拷贝');
const result2 = simpleDeepClone(testData);
console.timeEnd('简化深拷贝');

console.time('JSON深拷贝');
const result3 = jsonDeepClone(testData);
console.timeEnd('JSON深拷贝');

// 局限性测试
console.log('\n=== 局限性测试 ===');
const specialObj = {
  func: function() { return 'hello'; },
  undef: undefined,
  symbol: Symbol('test'),
  bigint: BigInt(123),
  date: new Date(),
  regex: /test/gi,
  map: new Map([['key', 'value']]),
  set: new Set([1, 2, 3])
};

console.log('JSON深拷贝局限性:');
const jsonResult = jsonDeepClone(specialObj);
console.log('函数丢失:', jsonResult.func === undefined); // true
console.log('undefined丢失:', jsonResult.undef === undefined); // true
console.log('Symbol丢失:', jsonResult.symbol === undefined); // true

console.log('递归深拷贝完整性:');
const recursiveResult = deepClone(specialObj);
console.log('函数保留:', typeof recursiveResult.func === 'function'); // true
console.log('undefined保留:', recursiveResult.undef === undefined); // true
console.log('Symbol类型保留:', typeof recursiveResult.symbol === 'symbol'); // true